﻿using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using HiSportApplet.Application.Common.SqlSugar;
using HiSportApplet.Application.Service.Bas.MemberManagement.Dtos.BasVenueMemberDtos;
using HiSportApplet.Application.Service.Member.BasMemberManagement.Dtos;
using HiSportApplet.Core.Entity.Bas;
using HiSportApplet.Core.Entity.Member;
using HiSportApplet.Core.Enum;
using HiSportApplet.Core.Util;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using System.ComponentModel;

namespace HiSportApplet.Application.Service.Member.BasMemberManagement
{

    /// <summary>
    /// 场馆会员
    /// </summary>
    [ApiDescriptionSettings("会员", Tag = "场馆会员", SplitCamelCase = false)]
    public class BasMemberService : ITransient, IBasMemberService, IDynamicApiController
    {
        private readonly SqlSugarRepository<BasVenueMember> _basMemberRep;
        private readonly SqlSugarRepository<BasVenues> _basVenueRep;
        private readonly SqlSugarRepository<SysMember> _sysMemberRep;
        private readonly SqlSugarRepository<BasVenueMemberGrade> _basMemberGradeRep;
        private readonly SqlSugarRepository<BasMemberBind> _basMemberBindRep;


        public BasMemberService(
       SqlSugarRepository<BasVenueMember> basMemberRep,
       SqlSugarRepository<BasVenues> basVenueRep,
       SqlSugarRepository<SysMember> sysMemberRep,
       SqlSugarRepository<BasVenueMemberGrade> basMemberGradeRep,
       SqlSugarRepository<BasMemberBind> basMemberBindRep
        )
        {
            _basMemberRep = basMemberRep;
            _basVenueRep = basVenueRep;
            _sysMemberRep = sysMemberRep;
            _basMemberGradeRep = basMemberGradeRep;
            _basMemberBindRep = basMemberBindRep;
        }


        /// <summary>
        /// 创建场馆会员
        /// </summary>
        /// <returns></returns>
        [ApiDescriptionSettings(Name = "CreateMember"), HttpPost]
        [DisplayName("创建场馆会员")]
        public async Task<BasMemberBasicDto> CreateMember(CreateMemberInputDto input)
        {

            #region 参数验证

            ParamNull(input);
            var venuesId = input.VenuesId;
            if (venuesId <= 0) throw Oops.Oh("场馆信息必填");

            var sysMemberId = input.SysMemberId;
            if (sysMemberId <= 0) throw Oops.Oh("系统会员必填");

            #endregion

            #region 是否存在此场馆
            var venue = await _basVenueRep.GetFirstAsync(a => a.Id == venuesId);
            if (venue == null) throw Oops.Oh("不存在此场馆");
            var tenantId = venue.TenantId;
            #endregion

            #region 是否是系统会员
            var sysMember = await _sysMemberRep.GetFirstAsync(a => a.Id == sysMemberId);
            if (sysMember == null) throw Oops.Oh("不存在此系统会员");
            #endregion

            #region  此场馆是否有此场馆会员
            var bindData= await _basMemberBindRep.GetFirstAsync(a => a.TenantId == tenantId && a.SysMemberId == sysMemberId);
            if(bindData!=null) throw Oops.Oh("此用户已经是此场地的会员");
            #endregion


            #region 创建场馆会员

            //默认一个会员等级：获取默认的会员等级
            var grade = await _basMemberGradeRep.GetFirstAsync(a => a.TenantId == tenantId && a.IsDefault == true);
            var gradeId = grade == null ? 0 : grade.Id;

            var curMember = new BasVenueMember()
            {
                TenantId = tenantId,
                VenueId = venuesId,
                Name = sysMember.Name,
                HeadUrl = sysMember.HeadUrl,
                Sex = sysMember.Sex,
                Birthday = sysMember.Birthday,
                Phone = sysMember.Phone,
                SignupSource = SignupSourceTypeEnum.Applet,
                MemberGradeId = gradeId

            };
            var member = await _basMemberRep.InsertReturnEntityAsync(curMember);
            if (member == null) throw Oops.Oh("绑定失败");
            var memberId = member.Id;
            //写入关联表
            var memberBind = new BasMemberBind()
            {
                TenantId = tenantId,
                SysMemberId = sysMemberId,
                MemberId = memberId
            };
            await _basMemberBindRep.InsertAsync(memberBind);

            #endregion

            //返回会员信息：
            var result = member.Adapt<BasMemberBasicDto>();
            return result;
        }

        /// <summary>
        /// 查询场馆会员
        /// 会员ID查询;
        /// 场地ID+系统会员ID查询;
        /// 优先会员ID查询
        /// </summary>
        /// <returns></returns>
        [ApiDescriptionSettings(Name = "GetMember"), HttpPost]
        [DisplayName("查询场馆会员")]
        public async Task<BasMemberBasicDto> GetMember(GetMemberInputDto input)
        {
            #region 参数验证

            ParamNull(input);
            var tenantId = input.TenantId;
            if (tenantId <= 0) throw Oops.Oh("租户信息必填");

            var memberId = input.MemberId;
            var venuesId = input.VenuesId;
            var sysMemberId = input.SysMemberId;

            if ((memberId == null || !memberId.HasValue || memberId.Value <= 0) &&
                (venuesId == null || !venuesId.HasValue || venuesId.Value <= 0) &&
                (sysMemberId == null || !sysMemberId.HasValue || sysMemberId.Value <= 0)
                )
                throw Oops.Oh("参数有误:会员信息必填");

            BasVenueMember? member = null;
            //按照会员ID查询
            if (memberId != null && memberId.HasValue && memberId.Value > 0)
            {
                member = await _basMemberRep.GetFirstAsync(a => a.IsDelete == false && a.TenantId == tenantId && a.Id == memberId);
            }
            else
            {
                if (venuesId == null || !venuesId.HasValue || venuesId <= 0) throw Oops.Oh("场馆信息必填");
                if (sysMemberId == null || !sysMemberId.HasValue || sysMemberId <= 0) throw Oops.Oh("系统会员必填");

                //var bind=await  _basMemberBindRep.GetFirstAsync(a => a.TenantId == tenantId && a.SysMemberId == sysMemberId && a.IsDelete == false);


                // _basMemberRep.GetFirstAsync(a => a.TenantId == tenantId && a.VenueId == venuesId && a.IsDelete == false)

                var bindQuery = _basMemberBindRep.AsQueryable();
                var memberQuery = _basMemberRep.AsQueryable();

                member = await (memberQuery.InnerJoin<BasMemberBind>((a, b) => a.Id == b.MemberId && b.SysMemberId == sysMemberId)
                  .Where((a, b) => a.IsDelete == false && a.TenantId == tenantId && a.VenueId == venuesId &&
                  b.IsDelete == false && b.TenantId == tenantId && b.SysMemberId == sysMemberId)
                 .Select(a => new BasVenueMember { Id = a.Id.SelectAll(), })).FirstAsync();
            }

            if (member == null || member.Id <= 0) throw Oops.Oh("未查询到此会员");

            var result = member.Adapt<BasMemberBasicDto>();
            return result;
            #endregion

        }


        /// <summary>
        /// 场馆会员-分页查询
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [ApiDescriptionSettings(Name = "SearchVenueMember"), HttpPost]
        [DisplayName("查询场馆会员列表")]
        public async Task<SqlSugarPagedList<BasVenueMemberBasicDto>> SearchVenueMember(BasVenueMemberInputDto input)
        {
            ParamNull(input);
            var phone = input.Phone;

            //会员与场地联查  查询会员信息
            var memberQuery = _basMemberRep.AsQueryable().Where(a => a.IsDelete == false && a.Phone == input.Phone);
            var venuesQuery = _basVenueRep.AsQueryable().Where(a => a.IsDelete == false);
            var data = await memberQuery.InnerJoin<BasVenues>((a, b) => a.VenueId == b.Id)
                 .Where((a, b) => a.IsDelete == false && a.Phone == phone &&
                 b.IsDelete == false)
                 .Select((a, b) => new BasVenueMemberBasicDto
                 {
                     Id = a.Id.SelectAll(),
                     VenueName = b.VenuesName
                 })
                 .OrderByDescending(a => a.CreateTime)
                 .ToPagedListAsync(input.Page, input.PageSize);

            if (data == null || data.Items == null || !data.Items.Any()) return new SqlSugarPagedList<BasVenueMemberBasicDto>();

            var grades = new List<BasVenueMemberGrade>();
            #region 会员等级渲染

            var items = data.Items;
            var gradeIds = items.Where(a => a.MemberGradeId > 0).Select(a => a.MemberGradeId).Distinct().ToList();
            if (gradeIds.Any())
            {
                grades= _basMemberGradeRep.AsQueryable().Where(a => gradeIds.Contains(a.Id) && a.IsDelete == false).ToList();
                if (grades == null) grades = new List<BasVenueMemberGrade>();
            }
            #endregion


            foreach (var item in items)
            {
                #region 会员等级
               var curGrade= grades.FirstOrDefault(a => a.Id == item.MemberGradeId);
                item.MemberGradeName = curGrade==null?string.Empty: curGrade.Name;
                #endregion

            }

            return data;
        }
 

        /// <summary>
        /// 参数为NULL验证
        /// </summary>
        /// <param name="input"></param>
        private void ParamNull(object input)
        {
            if (input == null) throw Oops.Oh("参数错误:参数为NULL");
        }
    }
}


